package se19team1e.gui.awt;

import java.awt.Choice;
import java.awt.FlowLayout;
import java.awt.Panel;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.Calendar;
import java.util.Date;

/**
 * 
 * This is a helper field that allows selection of day/month/year
 * 
 * @author lai shiaw san
 *
 */
@SuppressWarnings("serial")
public class DateField extends Panel {

    /**
     * An awt combo box to select day.
     */
    private final Choice dayComboBox;

    /**
     * An awt combo box to select month.
     */
    private final Choice monthComboBox;

    /**
     * An awt combo box to select year.
     */
    private final Choice yearComboBox;
    
    /**
     * Keep track of the min year.
     */
    private final int minYear;
    
    /**
     * Construct the field with the min/max year range.
     */
    public DateField( int minYear, int maxYear ) {
        // set layout
        this.setLayout( new FlowLayout() );
        
        // keep track of min year
        this.minYear = minYear;
        
        // create year combo box
        this.yearComboBox = new Choice();
        do {
            this.yearComboBox.add( Integer.toString( minYear ) );
            ++minYear;
        } while ( minYear <= maxYear );
        this.yearComboBox.select( 0 );
        
        // create month combo box
        this.monthComboBox = new Choice();
        for ( int m = 1; m <= 12; ++m ) {
            this.monthComboBox.add( Integer.toString( m ) );
        }
        this.monthComboBox.addItemListener( new ItemListener() {
            @Override
            public void itemStateChanged( ItemEvent e ) {
                resetDayComboBox();
            }
        });
        
        // create day combo box
        this.dayComboBox = new Choice();
        for ( int m = 1; m <= 31; ++m ) {
            this.dayComboBox.add( Integer.toString( m ) );
        }
        this.resetDayComboBox();

        this.add( this.dayComboBox );
        this.add( this.monthComboBox );
        this.add( this.yearComboBox );
    }

    /**
     * Converts the input as a date.
     * <p>
     * Return null if unable to convert.
     * </p>
     * @return Input as date, or null if unable to convert.
     */
    @SuppressWarnings("deprecation")
    public Date getValueAsDate() {
        return new Date( getYearAsInt() - 1900, getMonthAsInt() - 1, getDayAsInt() );
    }

    /**
     * Reset all the selected choices
     * @param date 
     */
    public void resetValues(Date date) {
    	Calendar cal = Calendar.getInstance();
    	if (date!=null){
    		cal.setTime(date);
    	}
        this.yearComboBox.select(String.valueOf(cal.get(Calendar.YEAR)));
        this.monthComboBox.select(cal.get(Calendar.MONTH));
        this.resetDayComboBox();
        this.dayComboBox.select(cal.get(Calendar.DAY_OF_MONTH) - 1);
    }

    /**
     * Reset the day combo box's allowed days, base on the current selected month. 
     */
    private void resetDayComboBox() {
        Calendar c = Calendar.getInstance();
        // set the month and year, and default to day 1
        c.set( getYearAsInt(), getMonthAsInt() - 1, 1 );

        // move to next month, and minus 1 day
        c.add( Calendar.MONTH, 1 );
        c.add( Calendar.DATE, -1 );
        
        // get date
        int maxDate = c.get( Calendar.DAY_OF_MONTH);
        
        // make sure day combo box at least has this number, and not more
        while ( this.dayComboBox.getItemCount() <= maxDate ) {
            this.dayComboBox.add( Integer.toString( this.dayComboBox.getItemCount() + 1 ) );
        }
        
        // remove excessive
        while ( this.dayComboBox.getItemCount() > maxDate ) {
            this.dayComboBox.remove( this.dayComboBox.getItemCount() - 1 );
        }
    }

    /**
     * Get the selected day as an integer (1-31).
     * @return Selected day.
     */
    private int getDayAsInt() {
        return this.dayComboBox.getSelectedIndex() + 1;
    }

    /**
     * Get the selected month as an integer (1-12).
     * @return Selected month.
     */
    private int getMonthAsInt() {
        return this.monthComboBox.getSelectedIndex() + 1;
    }

    /**
     * Get the selected month as an integer.
     * @return Selected month.
     */
    private int getYearAsInt() {
        return this.minYear + this.yearComboBox.getSelectedIndex();
    }
    
    /**
     * Enables / Disables the dropdown lists of day, month and year fields.
     * @param bEnable boolean for enabling or disabling the fields.
     */
    public void enableDateFieldSelection(boolean bEnable) {
    	this.dayComboBox.setEnabled(bEnable);
    	this.monthComboBox.setEnabled(bEnable);
    	this.yearComboBox.setEnabled(bEnable);
    }

}
